import express, { Request, Response, Router } from 'express';
import { PrismaClient, WithdrawType } from '@prisma/client';
import { authMiddleware } from '../middleware/auth';
import { ApiResponse } from '../utils/response';
import { priceService } from '../services/priceService';

const router: Router = express.Router();
const prisma = new PrismaClient();

// 提交提现申请
router.post('/apply', authMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const userId = (req as any).userId;
    const { amount } = req.body;

    // 验证출금 금액
    if (!amount || isNaN(parseFloat(amount)) || parseFloat(amount) <= 0) {
      res.status(400).json(ApiResponse.error('출금 금액은 0보다 커야 합니다.'));
      return;
    }

    const withdrawAmount = parseFloat(amount);

    // 检查最小출금 금액限制
    if (withdrawAmount < 3000) { // 最小提现3千韩元
      res.status(400).json(ApiResponse.error('최소 출금 금액은 3,000원입니다.'));
      return;
    }

    // 检查用户余额
    let userBalance = await prisma.userBalance.findUnique({
      where: { userId }
    });

    // 如果没有余额记录，创建一个初始记录
    if (!userBalance) {
      userBalance = await prisma.userBalance.create({
        data: {
          userId,
          balance: 0,
          frozen: 0,
          total: 0
        }
      });
    }

    // 检查可用余额是否足够
    const availableBalance = userBalance.balance;
    const availableBalanceNumber = Number(availableBalance);
    if (availableBalanceNumber < withdrawAmount) {
      res.status(400).json(ApiResponse.error(`잔액이 부족합니다. 사용 가능 잔액: ${availableBalanceNumber.toLocaleString('ko-KR')}원`));
      return;
    }

    // 获取质押收益及NEAR价格，用于同步扣减可提现收益
    const [userStaking, nearPrice] = await Promise.all([
      prisma.userStaking.findFirst({ where: { userId } }),
      priceService.getNearPrice()
    ]);

    const availableRewardsNear = Number(userStaking?.availableRewards || 0);
    const maxRewardKrw = nearPrice > 0 ? availableRewardsNear * nearPrice : 0;
    const rewardPortionKrw = Math.min(maxRewardKrw, withdrawAmount);
    const rewardPortionNear = nearPrice > 0
      ? Number((rewardPortionKrw / nearPrice).toFixed(4))
      : 0;
    const safeRewardPortionNear = Math.min(rewardPortionNear, availableRewardsNear);
    const withdrawType = rewardPortionKrw > 0
      ? WithdrawType.STAKING_REWARD
      : WithdrawType.BALANCE;

    // 检查是否有待处理的提现申请
    const pendingWithdraw = await prisma.withdrawRecord.findFirst({
      where: {
        userId,
        status: 'PENDING'
      }
    });

    if (pendingWithdraw) {
      res.status(400).json(ApiResponse.error('처리되지 않은 출금 신청이 있습니다. 관리자 검토를 기다려 주세요.'));
      return;
    }

    // 获取用户银行信息
    const user = await prisma.user.findUnique({
      where: { id: userId },
      select: {
        withdrawalBank: true,
        withdrawalAccount: true,
        accountHolder: true
      }
    });

    if (!user) {
      res.status(404).json(ApiResponse.error('사용자 정보가 존재하지 않습니다.'));
      return;
    }

    // 使用事务创建提现记录并冻结金额
    const result = await prisma.$transaction(async (tx) => {
      // 创建提现记录
      const withdraw = await tx.withdrawRecord.create({
        data: {
          userId,
          amount: withdrawAmount,
          withdrawType,
          bankAccount: user.withdrawalAccount,
          bankName: user.withdrawalBank,
          accountHolder: user.accountHolder,
          status: 'PENDING',
          rewardNearAmount: safeRewardPortionNear
        }
      });

      // 冻结相应金额
      await tx.userBalance.update({
        where: { userId },
        data: {
          balance: { decrement: withdrawAmount },
          frozen: { increment: withdrawAmount }
        }
      });

      if (safeRewardPortionNear > 0 && userStaking) {
        await tx.userStaking.update({
          where: { userId },
          data: {
            availableRewards: {
              decrement: safeRewardPortionNear
            }
          }
        });
      }

      return withdraw;
    });

    res.json(ApiResponse.success({
      id: result.id,
      amount: result.amount,
      status: result.status,
      bankAccount: result.bankAccount,
      bankName: result.bankName,
      accountHolder: result.accountHolder,
      createdAt: result.createdAt
    }, '출금 신청이 접수되었으며 금액이 동결되었습니다. 관리자 검토를 기다려 주세요.'));
  } catch (error) {
    console.error('출금 신청 오류:', error);
    res.status(500).json(ApiResponse.error('출금 신청에 실패했습니다. 잠시 후 다시 시도해 주세요.'));
  }
});

// 获取提现历史记录
router.get('/history', authMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const userId = (req as any).userId;
    const { page = 1, limit = 20, status } = req.query;

    // 构建查询条件
    const where: any = { userId };
    if (status && status !== 'all') {
      where.status = status as string;
    }

    // 获取提现记录
    const withdraws = await prisma.withdrawRecord.findMany({
      where,
      select: {
        id: true,
        amount: true,
        status: true,
        bankAccount: true,
        bankName: true,
        accountHolder: true,
        adminNote: true,
        createdAt: true,
        processedAt: true
      },
      orderBy: { createdAt: 'desc' },
      skip: (Number(page) - 1) * Number(limit),
      take: Number(limit)
    });

    // 获取总记录数
    const total = await prisma.withdrawRecord.count({
      where
    });

    // 统计各상태的数量
    const statusCounts = await prisma.withdrawRecord.groupBy({
      by: ['status'],
      where: { userId },
      _count: {
        status: true
      }
    });

    const summary = {
      pending: Number(statusCounts.find(s => s.status === 'PENDING')?._count.status) || 0,
      confirmed: Number(statusCounts.find(s => s.status === 'CONFIRMED')?._count.status) || 0,
      failed: Number(statusCounts.find(s => s.status === 'FAILED')?._count.status) || 0,
      cancelled: Number(statusCounts.find(s => s.status === 'CANCELLED')?._count.status) || 0
    };

    // 将 Decimal 类型转换为数字
    const formattedWithdraws = withdraws.map(withdraw => ({
      ...withdraw,
      amount: Number(withdraw.amount)
    }));

    res.json(ApiResponse.success({
      records: formattedWithdraws,
      summary,
      pagination: {
        page: Number(page),
        limit: Number(limit),
        total: Number(total),
        totalPages: Math.ceil(Number(total) / Number(limit))
      }
    }));
  } catch (error) {
    console.error('출금 내역 조회 오류:', error);
    res.status(500).json(ApiResponse.error('출금 내역 조회에 실패했습니다.'));
  }
});

// 获取提现详情
router.get('/:id', authMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const userId = (req as any).userId;
    const { id } = req.params;

    const withdraw = await prisma.withdrawRecord.findFirst({
      where: {
        id: parseInt(id),
        userId
      },
      select: {
        id: true,
        amount: true,
        status: true,
        bankAccount: true,
        bankName: true,
        accountHolder: true,
        adminNote: true,
        createdAt: true,
        processedAt: true,
        user: {
          select: {
            name: true,
            idNumber: true
          }
        }
      }
    });

    if (!withdraw) {
      res.status(404).json(ApiResponse.error('출금 기록이 존재하지 않습니다.'));
      return;
    }

    res.json(ApiResponse.success(withdraw));
  } catch (error) {
    console.error('출금 상세 조회 오류:', error);
    res.status(500).json(ApiResponse.error('출금 상세 조회에 실패했습니다.'));
  }
});

// 取消提现申请（仅限待处理상태）
router.post('/:id/cancel', authMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const userId = (req as any).userId;
    const { id } = req.params;

    // 查找提现记录
    const withdraw = await prisma.withdrawRecord.findFirst({
      where: {
        id: parseInt(id),
        userId,
        status: 'PENDING'
      }
    });

    if (!withdraw) {
      res.status(404).json(ApiResponse.error('출금 기록이 없거나 취소할 수 없습니다.'));
      return;
    }

    // 使用事务取消提现申请并解冻金额
    const result = await prisma.$transaction(async (tx) => {
      // 更新提现상태为已取消
      const updatedWithdraw = await tx.withdrawRecord.update({
        where: { id: parseInt(id) },
        data: {
          status: 'CANCELLED',
          processedAt: new Date(),
          adminNote: '사용자가 직접 취소했습니다.'
        }
      });

      // 解冻金额，恢复到可用余额
      await tx.userBalance.update({
        where: { userId },
        data: {
          balance: { increment: withdraw.amount },
          frozen: { decrement: withdraw.amount }
        }
      });

      return updatedWithdraw;
    });

    res.json(ApiResponse.success(result, '출금 신청이 취소되었으며 동결된 금액이 해제되었습니다.'));
  } catch (error) {
    console.error('출금 신청 취소 오류:', error);
    res.status(500).json(ApiResponse.error('출금 신청 취소에 실패했습니다.'));
  }
});

// 获取提现限制信息
router.get('/limits/info', authMiddleware, async (req: Request, res: Response): Promise<void> => {
  try {
    const userId = (req as any).userId;

    // 获取用户余额
    const userBalance = await prisma.userBalance.findUnique({
      where: { userId }
    });

    // 获取今日提现总额
    const today = new Date();
    today.setHours(0, 0, 0, 0);
    const tomorrow = new Date(today);
    tomorrow.setDate(tomorrow.getDate() + 1);

    const todayWithdraws = await prisma.withdrawRecord.aggregate({
      where: {
        userId,
        status: { in: ['PENDING', 'CONFIRMED'] },
        createdAt: {
          gte: today,
          lt: tomorrow
        }
      },
      _sum: {
        amount: true
      }
    });

    const todayTotal = todayWithdraws._sum.amount || 0;
    const dailyLimit = 10000000; // 日限额1000万韩元
    const minAmount = 3000; // 最小출금 금액3千韩元
    const availableBalance = userBalance?.balance || 0;
    const availableBalanceNumber = Number(availableBalance);
    const remainingDailyLimit = Math.max(0, dailyLimit - Number(todayTotal));

    res.json(ApiResponse.success({
      availableBalance: availableBalanceNumber,
      dailyLimit,
      todayWithdrawn: Number(todayTotal),
      remainingDailyLimit,
      minAmount,
      canWithdraw: availableBalanceNumber >= minAmount && remainingDailyLimit >= minAmount
    }));
  } catch (error) {
    console.error('출금 제한 정보 조회 오류:', error);
    res.status(500).json(ApiResponse.error('출금 제한 정보 조회에 실패했습니다.'));
  }
});

export default router;
